unit uForma;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, JvMenus, ImgList, JvImageList, ActnList, JvVersionControlActions,
  JvExControls, JvButton, JvTransparentButton, ExtCtrls, JvExExtCtrls, JvExtComponent,
  JvPanel, JvGradientHeaderPanel, JvImage, JvFullColorDialogs, JvComponentBase, JvSystemPopup, ToolWin, ComCtrls, JvExComCtrls, JvToolBar, StdCtrls,
  JvBalloonHint;

type

  TMyWindowState = (MyNormal, MyMinimized, MyMaximizedAllScreen, MyMaximizedDesktop);

  TControlOnMouseMove = class(TControl)
    published
    property OnMouseMove;
  end;


  TfForma = class(TForm)
    jvGHPanelTop: TJvGradientHeaderPanel;
    jvGHPanelButton: TJvGradientHeaderPanel;
    JvVersionControlActionList: TJvVersionControlActionList;
    actCloseForm: TAction;
    JvImageListAllButton: TJvImageList;
    JvPopupMenuPasekTop: TJvPopupMenu;
    Zamknij1: TMenuItem;
    actMaxForm: TAction;
    tbtnMax: TJvTransparentButton;
    tbtnClose: TJvTransparentButton;
    tbtnNormal: TJvTransparentButton;
    actNormalForm: TAction;
    jvPResizeForm: TJvPanel;
    jvPanelLeft: TJvPanel;
    jvPanelRight: TJvPanel;
    jvPanelButton: TJvPanel;
    jvPanelTop: TJvPanel;
    JvGHPanelMaster: TJvGradientHeaderPanel;
    tbtnMin: TJvTransparentButton;
    actMinForm: TAction;
    JvImageListPasekButton: TJvImageList;
    JvImageIcon: TJvImage;
    JvToolBarMainMenu: TJvToolBar;
    JvMainMenu: TJvMainMenu;
    JvBalloonHint: TJvBalloonHint;
    JvGradientHeaderPanel1: TJvGradientHeaderPanel;
    procedure jvGHPanelTopMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure actCloseFormExecute(Sender: TObject);
    procedure actMaxFormExecute(Sender: TObject);
    procedure actNormalFormExecute(Sender: TObject);
    procedure jvPResizeFormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure jvPanelLeftMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure jvPanelButtonMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure JvPanelRightMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure jvPanelTopMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure RefreshForm(Sender: TObject; WinState : TMyWindowState);
    procedure jvGHPanelTopDblClick(Sender: TObject);
    procedure actMinFormExecute(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
    MyWindowsState : TMyWindowState;
    MyNormalWinStateHeight : integer;
    MyNormalWinStateLeft : integer;
    MyNormalWinStateTop : integer;
    MyNormalWinStateWidth : integer;
    FformMaximizedAllScreen : boolean;
    iShowTimeHint : integer;
    LastShowHintControl : TObject;
  public
    { Public declarations }
    {**
      * zmienna FormMaximizedAllScreen okresla czy skalijemy rozmoar okna na Maximim ekranu z zakryciem  paska zadan
      * true - form na caly ekran monitora
      * false - forma na calym pulpicie, widocznym paskiem zadan
    *}
    property FormMaximizedAllScreen : boolean read FformMaximizedAllScreen write FformMaximizedAllScreen default true;
    function MessageBox(const Text, Caption: PChar; Flags: Longint): Integer;
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  end;

var
  fForma: TfForma;

implementation

uses
  MultiMon;

{$R *.dfm}

procedure TfForma.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.WndParent := GetDesktopWindow;
//  with Params do ExStyle := ExStyle or WS_EX_TOOLWINDOW or WS_EX_APPWINDOW;
end;

procedure ExtraMaximize(MyForm: TForm);
begin
  if FindWindow('Shell_TrayWnd',nil) = 0 then
    MyForm.WindowState := wsMaximized
  else with MyForm do
  begin
    WindowState:=wsNormal;
    BorderStyle:=bsSingle;
    Top:=0;
    Left:=0;
    Width:=GetSystemMetrics(SM_CXSCREEN);
    Height:=GetSystemMetrics(SM_CYSCREEN)+GetSystemMetrics(SM_CYCAPTION);
  end;
end;
function TfForma.MessageBox(const Text, Caption: PChar; Flags: Longint): Integer;
var
   ActiveWindow, TaskActiveWindow: HWnd;
   WindowList: Pointer;
   MBMonitor, AppMonitor: HMonitor;
   MonInfo: TMonitorInfo;
   Rect: TRect;
   FocusState: TFocusState;
begin
   ActiveWindow := Application.ActiveFormHandle;
   if ActiveWindow = 0 then
     TaskActiveWindow := Handle
   else
     TaskActiveWindow := ActiveWindow;
   MBMonitor := MonitorFromWindow(ActiveWindow, MONITOR_DEFAULTTONEAREST);
   AppMonitor := MonitorFromWindow(Handle, MONITOR_DEFAULTTONEAREST);
   if MBMonitor <> AppMonitor then
   begin
     MonInfo.cbSize := Sizeof(TMonitorInfo);
     GetMonitorInfo(MBMonitor, @MonInfo);
     GetWindowRect(Handle, Rect);
     SetWindowPos(Handle, 0,
       MonInfo.rcMonitor.Left + ((MonInfo.rcMonitor.Right -
MonInfo.rcMonitor.Left) div 2),
       MonInfo.rcMonitor.Top + ((MonInfo.rcMonitor.Bottom -
MonInfo.rcMonitor.Top) div 2),
       0, 0, SWP_NOACTIVATE or SWP_NOREDRAW or SWP_NOSIZE or SWP_NOZORDER);
   end;
   WindowList := DisableTaskWindows(ActiveWindow);
   FocusState := SaveFocusState;
   if UseRightToLeftReading then Flags := Flags or MB_RTLREADING;
   try
     Result := Windows.MessageBox(TaskActiveWindow, Text, Caption, Flags);
   finally
     if MBMonitor <> AppMonitor then
       SetWindowPos(Handle, 0,
         Rect.Left + ((Rect.Right - Rect.Left) div 2),
         Rect.Top + ((Rect.Bottom - Rect.Top) div 2),
         0, 0, SWP_NOACTIVATE or SWP_NOREDRAW or SWP_NOSIZE or
SWP_NOZORDER);
     EnableTaskWindows(WindowList);
     SetActiveWindow(ActiveWindow);
     RestoreFocusState(FocusState);
   end;
end;

procedure TfForma.RefreshForm(Sender: TObject; WinState : TMyWindowState);
var
  R: TRect;
  nWinState : TWindowState;
  hmon: HMONITOR;
  mi: TMonitorInfo;
begin
  MyWindowsState := WinState;
  if (WinState = MyMaximizedAllScreen) or (WinState = MyMaximizedDesktop) then
  begin
    tbtnNormal.Visible := true;
    tbtnMax.Visible := false;
    jvPResizeForm.Visible := false;
    jvPResizeForm.Visible := true;
    jvPanelLeft.Visible := false;
    jvPanelRight.Visible := false;
    jvPanelTop.Visible := false;
    jvGHPanelTop.GradientCursor := crDefault;
    jvGHPanelTop.LabelCursor := crDefault;
    jvPanelButton.Visible := false;
    jvPResizeForm.Visible := false;

    if WinState = MyMaximizedAllScreen then
      nWinState := wsMaximized
    else
    begin
      //zapamietujemy stary rozmiar okna
      MyNormalWinStateHeight := Self.Height;
      MyNormalWinStateLeft := Self.Left;
      MyNormalWinStateTop := Self.Top;
      MyNormalWinStateWidth := Self.Width;
      nWinState := wsNormal;
      hmon := MonitorFromWindow(Handle, MONITOR_DEFAULTTONEAREST);
      FillChar(mi, SizeOf(mi), 0);
      mi.cbSize := SizeOf(mi);
      GetMonitorInfo(hmon, @mi);
      if (mi.dwFlags and MONITORINFOF_PRIMARY) = 1 then
      begin
        //SystemParametersInfo(SPI_GETWORKAREA,0,@R,0);
        //Self.Height := Screen.MonitorFromWindow(Handle).Height - (Screen.MonitorFromWindow(Handle).Height - r.Bottom + r.Top);
        Self.Height := mi.rcWork.Bottom;
      end else
        Self.Height := Screen.MonitorFromWindow(Handle).Height;

      Self.Top := Screen.MonitorFromWindow(Handle).Top;
      Self.Left := Screen.MonitorFromWindow(Handle).Left;
      Self.Width := Screen.MonitorFromWindow(Handle).Width;

    end;
  end else begin
    tbtnNormal.Visible := false;
    tbtnMax.Visible := true;
    jvPResizeForm.Visible := true;
    jvPanelLeft.Visible := true;
    jvPanelRight.Visible := true;
    jvPanelTop.Visible := true;
    jvGHPanelTop.GradientCursor := crSizeAll;
    jvGHPanelTop.LabelCursor := crSizeAll;
    jvPanelButton.Visible := true;
    jvPResizeForm.Visible := true;
    if WinState = MyMinimized then
      nWinState := wsMinimized
    else
    begin
      Self.Height := MyNormalWinStateHeight;
      Self.Left := MyNormalWinStateLeft;
      Self.Top := MyNormalWinStateTop;
      Self.Width := MyNormalWinStateWidth;
      nWinState := wsNormal;
    end;
  end;
  jvPResizeForm.Font.Color := jvGHPanelTop.LabelFont.Color;


//  ShowMessage(IntToStr(Screen.Height - r.Bottom + r.Top));
  //Screen.Height - r.Bottom + r.Top;

  Self.WindowState := nWinState;
  //ExtraMaximize(Self);
end;
procedure TfForma.actCloseFormExecute(Sender: TObject);
begin
  Self.Close;
end;

procedure TfForma.actMaxFormExecute(Sender: TObject);
var
  Task: THandle;
begin
  if (FindWindow('Shell_traywnd', nil) <> 0) and (not FormMaximizedAllScreen) then
    RefreshForm(Sender,MyMaximizedDesktop)
  else
    RefreshForm(Sender,MyMaximizedAllScreen);
end;

procedure TfForma.actMinFormExecute(Sender: TObject);
begin
  RefreshForm(Sender,MyMinimized);
end;

procedure TfForma.actNormalFormExecute(Sender: TObject);
begin
  RefreshForm(Sender,MyNormal);
end;

procedure TfForma.FormCreate(Sender: TObject);
var
  i : integer;
begin
  //jesli mamy jakis element Mianmenu to wyswetlamy manu
  if Self.JvMainMenu.Items.Count > 0 then
  begin
    Self.JvToolBarMainMenu.Visible := true;
    Self.JvToolBarMainMenu.Menu := Self.JvMainMenu;
    //for i := 0 to Self.Menu.Items.Count - 1 do
    //  Self.Menu.Items[i].Visible := true;
  end else
    Self.JvToolBarMainMenu.Visible := false;

  Application.ProcessMessages;
  iShowTimeHint := 1000;
  LastShowHintControl := nil;

  for i := 0 to Self.ComponentCount - 1 do
  begin
    if (Self.Components[i] is TControl) then
      if trim((Self.Components[i] as TControl).Hint) <> '' then
      begin
        TControlOnMouseMove(Self.Components[i]).OnMouseMove := FormMouseMove;
      end;
  end;

  Self.DoubleBuffered := true;
  Self.Caption := jvGHPanelTop.LabelCaption;
  JvImageIcon.Picture.Icon := Self.Icon;//Application.Icon;
  MyNormalWinStateHeight := Self.Height;
  MyNormalWinStateLeft := Self.Left;
  MyNormalWinStateTop := Self.Top;
  MyNormalWinStateWidth := Self.Width;
  RefreshForm(Sender, MyNormal);
end;

procedure TfForma.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  if LastShowHintControl <> sender then
  begin
    LastShowHintControl := Sender;
    JvBalloonHint.CancelHint;
  end;
  try
    if Sender is TJvTransparentButton then
     if not JvBalloonHint.Active then
        JvBalloonHint.ActivateHint(TControl(Sender), (Sender as TJvTransparentButton).Hint, '', iShowTimeHint);

    if Sender is TJvGradientHeaderPanel then
     if not JvBalloonHint.Active then
        JvBalloonHint.ActivateHint(TControl(Sender), (Sender as TJvGradientHeaderPanel).Hint, '', iShowTimeHint);
  finally

  end;
end;

procedure TfForma.jvGHPanelTopDblClick(Sender: TObject);
begin
  if Self.MyWindowsState = MyNormal then
    actMaxForm.Execute
  else if (Self.MyWindowsState = MyMaximizedAllScreen) or (Self.MyWindowsState = MyMaximizedDesktop) then
    actNormalForm.Execute;
end;

procedure TfForma.jvGHPanelTopMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  p: TPoint;
begin
  if (Button = mbLeft) and not (Self.MyWindowsState in [MyMaximizedAllScreen, MyMaximizedDesktop]) then
  begin
    ReleaseCapture;
    SendMessage(Self.Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
  end;
  if Button = mbRight then
  begin
    GetCursorPos(p);
    JvPopupMenuPasekTop.Popup(p.X, p.Y);
  end;
end;

procedure TfForma.jvPanelTopMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbLeft then
  begin
    ReleaseCapture;
    Self.Perform(Wm_SysCommand, SC_size +3,0);
  end;
end;

procedure TfForma.jvPanelButtonMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbLeft then
  begin
    if Sender is TJvpanel then
    begin
      ReleaseCapture;
      Self.Perform(Wm_SysCommand, SC_size + (Sender as TJvPanel).Tag,0);
    end;
  end;
end;

procedure TfForma.jvPanelLeftMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbLeft then
  begin
    ReleaseCapture;
    Self.Perform(Wm_SysCommand, SC_size +1,0);
  end;
end;

procedure TfForma.JvPanelRightMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbLeft then
  begin
    ReleaseCapture;
    Self.Perform(Wm_SysCommand, SC_size +2,0);
  end;
end;

procedure TfForma.jvPResizeFormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbLeft then
  begin
    ReleaseCapture;
    Self.Perform(Wm_SysCommand, SC_size +8,0);
  end;
end;

end.
